package com.ellecity06.common.ktx

import android.R
import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.graphics.RectF
import android.os.Build
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.Window
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import com.ellecity06.common.utils.appContext
import com.gyf.immersionbar.ktx.navigationBarHeight
import com.gyf.immersionbar.ktx.statusBarHeight
import kotlin.math.abs

/**
 * @author ellecity06
 * @time 2023/2/22 15:08
 * @des
 */
private var sDecorViewDelta: Int = 0
private const val TAG_ON_GLOBAL_LAYOUT_LISTENER = -8

/**
 * 注册键盘状态监听
 */
fun Window?.registerSoftInputChangedListener(listener: (height: Int) -> Unit) {
    if (this==null) return
    val flags = this.attributes.flags
    if ((flags and WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0) {
        this.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
    }
    val contentView = this.findViewById<FrameLayout>(R.id.content)
    val decorViewInvisibleHeightPre = intArrayOf(getDecorViewInvisibleHeight(this))
    val onGlobalLayoutListener = OnGlobalLayoutListener {
        val height: Int = getDecorViewInvisibleHeight(this)
        if (decorViewInvisibleHeightPre[0] != height) {
            listener.invoke(height)
            decorViewInvisibleHeightPre[0] = height
        }
    }
    contentView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener)
    contentView.setTag(TAG_ON_GLOBAL_LAYOUT_LISTENER, onGlobalLayoutListener)
}

fun Window?.unregisterSoftInputChangedListener() {
    if (this==null) return
    val contentView = this.findViewById<View>(R.id.content) ?: return
    val tag = contentView.getTag(TAG_ON_GLOBAL_LAYOUT_LISTENER)
    if (tag is OnGlobalLayoutListener) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            contentView.viewTreeObserver.removeOnGlobalLayoutListener(tag)
        }
    }
}

private fun Window.getDecorViewInvisibleHeight(window: Window): Int {
    val decorView = window.decorView
    val outRect = Rect()
    decorView.getWindowVisibleDisplayFrame(outRect)
    Log.d(
        "KeyboardUtils", "getDecorViewInvisibleHeight: "
                + (decorView.bottom - outRect.bottom)
    )
    val delta = abs((decorView.bottom - outRect.bottom).toDouble()).toInt()
    if (delta <= appContext.navigationBarHeight + appContext.statusBarHeight) {
        sDecorViewDelta = delta
        return 0
    }
    return delta - sDecorViewDelta
}

fun Fragment?.getSystemWindow(isEmbeddedFragment: Boolean = false): Window? {
    val windowFragment = if (isEmbeddedFragment) {
        this?.parentFragment
    } else {
        this
    }
    val window: Window? = if (windowFragment is DialogFragment) {
        windowFragment.dialog?.window
    } else {
        windowFragment?.activity?.window
    }
    return window
}

fun Activity.hideSoftInputFromWindow() {
    val parentImm: InputMethodManager =
        getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    if (parentImm.isActive) {
        val view = currentFocus
        if (null != view) {
            parentImm.hideSoftInputFromWindow(
                view.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }
}

/**
 * 隐藏键盘,过滤掉了当前的editText
 */
fun Activity.hideSoftKeyboard(event: MotionEvent?) {
    try {
        if (event?.action == MotionEvent.ACTION_DOWN) {
            val focusView = currentFocus
            //除了点击EidtText自身区域的其他任何区域，都将键盘收起
            if (null != focusView && null != focusView.windowToken && !isTouchView(
                    event,
                    focusView
                )
            ) {
                hideSoftInputFromWindow()
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

/**
 * 是否触摸了当前焦点控件
 * @param event
 * @param focusView
 * @return
 */
private fun isTouchView(event: MotionEvent?, focusView: View?): Boolean {
    if (null == event || null == focusView) {
        return false
    }
    val x = event.x
    val y = event.y
    val outLocation = IntArray(2)
    focusView.getLocationOnScreen(outLocation)
    val rectF = RectF(
        outLocation[0].toFloat(),
        outLocation[1].toFloat(),
        (outLocation[0] + focusView.width).toFloat(),
        (outLocation[1] + focusView.height).toFloat()
    )
    return x >= rectF.left && x <= rectF.right && y >= rectF.top && y <= rectF.bottom
}
